<!-- Created by henian.xu on 2018/3/5. -->

<template>
    <div class="input-number">
        <button
            :class="['minus',{'disabled':disabled||minusDisabled}]"
            @click.stop.prevent="onMinus"
        >
            <i class="f-icon">&#xf068;</i>
        </button>
        <div
            class="input"
            v-if="noInput">{{ currValue }}</div>
        <input
            v-else
            type="number"
            v-model.number="currValue"
            :disabled="disabled"
            @input="onInput"
        >
        <button
            :class="['plus',{'disabled':disabled||plusDisabled}]"
            @click.stop.prevent="onPlus"
        >
            <i class="f-icon">&#xf067;</i>
        </button>
    </div>
</template>

<script>
import emitter from '~/mixins/emitter';

export default {
    name: 'InputNumber',
    mixins: [emitter],
    data() {
        return {
            // currValue: this.value,
        };
    },
    props: {
        value: {
            type: [Number, String],
            default() {
                return 0;
            },
        },
        inputReadonly: {
            type: Boolean,
            default: true,
        },
        min: {
            type: Number,
            default() {
                return NaN;
            },
        },
        max: {
            type: Number,
            default() {
                return NaN;
            },
        },
        step: {
            type: Number,
            default() {
                return 1;
            },
        },
        noInput: {
            type: Boolean,
            default: false,
        },
        disabled: {
            type: Boolean,
            default: false,
        },
    },
    computed: {
        currValue: {
            get() {
                return this.value;
            },
            set(val) {
                this.$emit('input', val);
                this.dispatch('formItem', 'x.form.change', [val]);
            },
        },
        minusDisabled() {
            const val = +this.currValue;
            const min = +this.min;
            return val <= +min || val - this.step < min;
        },
        plusDisabled() {
            const val = +this.currValue;
            const max = +this.max;
            return val >= +this.max || val + this.step > max;
        },
    },
    watch: {
        /* value: {
                handler(val, oldVal) {
                    console.log(val, oldVal);
                },
                immediate: true,
            }, */
        max: {
            handler(val) {
                /*
                    * TODO: 因为 max min 是外部传进来的数据，所以 max 不一定大于 min
                    * 导致 value 的值可能小于 min 或大于 max
                    * 这种情况应该 是外部数数据规范吗？
                    * */
                if (isNaN(val)) return;
                if (this.currValue > val) {
                    if (val > this.min) {
                        this.currValue = val;
                    } else {
                        this.currValue = this.min;
                    }
                }
            },
            immediate: true,
        },
        min: {
            handler(val) {
                if (isNaN(val)) return;
                if (this.currValue < val) {
                    if (val < this.max) {
                        this.currValue = val;
                    } else {
                        this.currValue = this.max;
                    }
                }
            },
            immediate: true,
        },
    },
    methods: {
        onMinus() {
            if (this.disabled) return;
            if (this.minusDisabled) {
                this.$emit('minusdisabled');
                return;
            }
            const value = this.currValue - this.step;
            if (value < this.min) {
                this.currValue = this.min;
            } else {
                this.currValue = value;
            }
            // this.$emit('input', value);
            // this.dispatch('formItem', 'x.form.blur', [value]);
            // this.dispatch('formItem', 'x.form.change', [value]);
        },
        onPlus() {
            if (this.disabled) return;
            if (this.plusDisabled) {
                this.$emit('plusdisabled');
                return;
            }
            const value = this.currValue + this.step;
            if (value > this.max) {
                this.currValue = this.max;
            } else {
                this.currValue = value;
            }
            // this.$emit('input', value);
            // this.dispatch('formItem', 'x.form.change', [value]);
        },
        onInput() {
            this.$nextTick(() => {
                if (this.currValue > this.max) {
                    this.currValue = this.max;
                } else if (this.currValue < this.min) {
                    this.currValue = this.min;
                }
            });
            // this.$emit('input', this.currValue);
            // this.dispatch('formItem', 'x.form.change', [this.currValue]);
        },
    },
};
</script>

<style lang="scss">
@import '~/assets/style/_index.scss';

$form-item-height: 30px;

.input-number {
    display: inline-flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    border: 1px solid $color-border;

    > button {
        appearance: none;
        //border: 1px solid $color-border;
        background-color: #fff;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        height: $form-item-height;
        width: $form-item-height;
        text-align: center;
        color: $gray7;
        outline: none;
        font-size: 14px;
        cursor: pointer;

        &.disabled {
            border-color: $gray5;
            color: $gray5;
        }
        &.plus {
            &.disabled {
                background-color: $gray5;
                border-color: $gray5;
            }
        }
    }
    > .input {
        appearance: none;
        display: block;
        padding: 0 $padding-small;
        text-align: center;
        /*font-size: 0.3rem;*/
        min-width: 1em;
        line-height: $form-item-height;
        outline: none;
    }
    > input {
        appearance: none;
        width: 4em;
        text-align: center;
        padding: 0 $padding;
        height: $form-item-height;
        outline: none;

        &:disabled {
            background-color: transparent;
            color: $gray6;
        }
        &::-webkit-outer-spin-button,
        &::-webkit-inner-spin-button {
            appearance: none;
        }
    }
}
</style>
